Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement graph binary protocol #217

Open
wants to merge 56 commits into
base: master
Choose a base branch
from

Conversation

criminosis
Copy link
Contributor

@criminosis criminosis commented Nov 9, 2024

@wolf4ood wanted to give you a heads up of the PR coming. If you get a chance please look at it while it's in this preliminary draft stage because I've made some significant overhauls and it'd be nice to get your feedback before I continue. It's no longer in draft.

I'll annotate particular areas below 👍 .

But in addition to implementing the GraphBinaryV1 protocol this PR makes a few other changes:

  • Parmeterizes tests
    • I noticed it looked like the test files were heavily copy pastes of each other. I blended the first duo together integration_traversal and integration_traversal_v2 and parameterized it eventually replacing the original duo. This way the new GraphBinaryV1 protocol is equally tested as the two prior serializers by running the same tests. I did have to make tweaks to smooth small differences (namely differences in output key types in maps) and the V2 serializer doesn't appear to support some things, so its opted out where needed
  • I removed the mapping of is(<literal_value>)
    • It didn't seem like that was necessary during comparisons with the reference Java GraphBinary implementation and it caused problems, its unchanged though for within where clauses
  • Added derive flag to tests, it didn't appear they were previously being ran
  • Implemented some backwards compatibility mapping logic for Map get and try_get elaborated below
  • Added support for JG's custom serialization type for custom vertex ids, also parameterized the custom vertex id tests

I intend to continue this next week, parameterizing the remaining test files so GraphBinary can piggyback on the tests that already exist 👍 .

Ok(Response {
request_id: Some(middle_form.request_id),
result: ResponseResult {
data: serializer_v2::deserializer_v2(&middle_form.result.data).map(Some)?,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a notable change. Previously the result.data would only be parsed depending on the status code. To normalize the disjoint (de)serializers I go ahead and attempt to parse it regardless, but handle its omission via a None in the normalized type.

@criminosis
Copy link
Contributor Author

Also looks like there's something up with the grocv status?

@criminosis criminosis marked this pull request as ready for review November 13, 2024 18:18
@criminosis
Copy link
Contributor Author

@wolf4ood flipping this to ready since I've completed what I had left outstanding. Let me know what you think, as always happy to make changes.

About a net negative 1k lines despite the graph binary protocol being added from parameterizing all the tests. This means any future protocol that gets added will just need to be added as an additional annotation in tests/common.rs and it will flow down to all the tests as an additional case. But means the graph binary protocol is now as tested as the prior protocols.

There was a few tests that were adjusted namely either skipping the older GraphSONV2 protocol because it doesn't support the needed message type or modifying the assertions to handle the different response type GraphBinary returns, usually making fallback assertions on the richer T (as in T::Id) type instead of simply a String("id") being the key in a hashmap, etc.

On the note of tests, the actual tests are passing but the grcov GH Action seems broken which is what is causing the overarching red x on the result for the PR FYSA. I believe that's out of my control to fix in this PR, but happy to rebase if you fix it 👍 .

@criminosis
Copy link
Contributor Author

As previously mentioned so long as people were using the default GraphSONV3 (de)serializer and not explicitly setting it I believe this should be a transparent change. I didn't change the default, just added the new protocol as an option after renaming the enum. Figured changing the default is something that is your discretion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added derive flag to tests, notice the derive tests weren't being ran

Comment on lines +95 to +110
fn backwards_compatability_get(&self, key: GKey) -> Option<&GValue> {
//The GraphBinary protocol may be returning properties
//as the distinct "T" type (T::Id) whereas older protocols
//would have just sent them as GKey::String("id"), etc
//This function is intended as a fallback for backwards compatability that if a caller
//requests a get or try_get for "id" that we also then attempt it T::Id or one of its siblings
//This also maintains the representation needed for the derive crate to find
//the types since the derive crate can't discriminate between a vertex property called "id"
//or a T::Id since they're both just called "id"
match key {
GKey::String(string) => match TryInto::<T>::try_into(string.as_str()) {
Ok(fallback_key) => self.0.get(&fallback_key.into()),
Err(_) => None,
},
_ => None,
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wolf4ood really wanted to call attention to this. Originally I was intended to just make users make the jump to calling a map.get(T::Id) vs map.get("id") but once I fixed the derive tests I hit a wall that the derive macro logic can't make that jump (I think?).

Namely the derive macro can't really know if the final struct should be using a property called "id" or "T::id" now that GraphBinary discriminates between the two. So I was hesitant to "fix" the problem on that side.

Doing it here means anyone who was doing map.get("id") will transparently get switched to map.get(T::id) under the covers if their initial get attempt returns a None now. That way it's only a perf hit as a fallback, whereas the derive macro would have had to do that for every property I think.

Anyways, wanted to call this out because it's kind of a catch 22 situation that we're forced into I think because of the derive macros.

Comment on lines +31 to +32
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default JanusGraph doesn't have GraphBinary enabled so the custom vertex id tests were failing as the serializer wasn't enabled. This config enables them here and the config is then mounted into the needed spot in the docker-compose file

@criminosis criminosis marked this pull request as draft November 14, 2024 20:41
@criminosis
Copy link
Contributor Author

Flipping back to draft. While integrating this branch into my application logic I found some placed JanusGraph does things a little bit differently. Also discovered edge properties aren't being serialized in either GraphSONV2 or GraphSONV3, so fixing that as well atm.

@criminosis
Copy link
Contributor Author

K, back to ready. Completed trying it out with my application and at least for my purposes it all works.

@criminosis criminosis marked this pull request as ready for review November 14, 2024 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant